using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Mbl.ParameterizedTest.AcceptanceTests.CalculatorTests
{
    public class ExpectedFailedTestCases : ExpectedExceptionBaseAttribute
    {
        private readonly int[] _expectedFailedTestNrs;
        
        public ExpectedFailedTestCases(params int[] expectedFailedTestNrs)
        {
            _expectedFailedTestNrs = expectedFailedTestNrs;            
        }

        protected override void Verify(Exception exception)
        {
            var fail = exception as AssertFailedException;
            if (fail == null)
            {
                throw exception;
            }

            var errorMatcher = new Regex($"  Test 0*(?<testNr>[0-9]+)");
            var actualFailedTests = errorMatcher.Matches(fail.Message)
                .Cast<Match>()
                .Select(match => int.Parse(match.Groups["testNr"].Value))
                .ToList();

            var resultAggregator = new ErrorAggregator();
            foreach (var expectedFailedtest in _expectedFailedTestNrs.Except(actualFailedTests))
            {                
                resultAggregator.AddError($"Expected test number {expectedFailedtest} to fail");
            }

            foreach (var unexpectedFailedtest in actualFailedTests.Except(_expectedFailedTestNrs))
            {
                resultAggregator.AddError($"Test number {unexpectedFailedtest} failed unexpectedly");
            }

            resultAggregator.FailIfAnyErrors();
        }
    }
}